package com.ruoyi.business.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.mapper.WsdRefundTransactionsMapper;
import com.ruoyi.business.service.IRefundApprovalService;
import com.ruoyi.business.service.IWsdMealRefundsService;
import com.ruoyi.business.service.IWsdRechargeRefundService;
import com.ruoyi.business.service.IWsdRefundTransactionsService;
import com.ruoyi.common.core.domain.dto.WsdMealRefundsDTO;
import com.ruoyi.common.core.domain.dto.WsdPaymentRecordsDTO;
import com.ruoyi.common.core.domain.dto.WsdRefundManagementDTO;
import com.ruoyi.common.core.domain.entity.RefundApproval;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WsdRechargeRefund;
import com.ruoyi.common.core.domain.entity.WsdRefundTransactions;
import com.ruoyi.common.core.domain.table.OrderFoodTable;
import com.ruoyi.common.core.domain.table.OrderFoodVOTable;
import com.ruoyi.common.core.domain.vo.ChartDataVO;
import com.ruoyi.common.core.domain.vo.OrderPeopleNumVO;
import com.ruoyi.common.core.domain.vo.RefundManagementVO;
import com.ruoyi.common.core.domain.vo.WsdRefundTransactionsVO;

import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;

import java.util.List;
import java.util.Map;

import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * <p>
 * 退款流水表，记录所有退款相关的信息 服务实现类
 * </p>
 *
 * @author wwq
 * @since 2024-05-20
 */
@Service
public class WsdRefundTransactionsServiceImpl extends ServiceImpl<WsdRefundTransactionsMapper, WsdRefundTransactions> implements IWsdRefundTransactionsService {
    @Autowired
    private WsdRefundTransactionsMapper wsdRefundTransactionsMapper;
    @Autowired
    private IWsdMealRefundsService wsdMealRefundsService;
    @Autowired
    private IWsdRechargeRefundService wsdRechargeRefundService;
    @Autowired
    private IRefundApprovalService refundApprovalService;
    @Autowired
    private ISysUserService userService;

    @Override
    public List<WsdRefundTransactions> selectWsdRefundTransactionsList(WsdRefundTransactions wsdRefundTransactions)
    {
        return wsdRefundTransactionsMapper.selectWsdRefundTransactionsList(wsdRefundTransactions);
    }

    @Override
    public List<WsdRefundTransactionsVO> listRefund(WsdPaymentRecordsDTO wsdPaymentRecordsDTO) {
        SysUser user = getLoginUser().getUser();
        Long schoolId = user.getSchoolId();
        wsdPaymentRecordsDTO.setStatus(2);
        if (!user.isAdmin()) {
            if (wsdPaymentRecordsDTO.getSchoolsId()==null) {
                wsdPaymentRecordsDTO.setSchoolsId( schoolId );
            }
        }
        // 处理时间范围
        if (wsdPaymentRecordsDTO.getType() != null) {
            LocalDate today = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            switch (wsdPaymentRecordsDTO.getType()) {
                case 0: // 今天
                    wsdPaymentRecordsDTO.setRechargeTimeStart(today.atStartOfDay().format(formatter));
                    wsdPaymentRecordsDTO.setRechargeTimeEnd(today.atTime(23, 59, 59).format(formatter));
                    break;
                case 1: // 本周
                    LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                    LocalDate endOfWeek = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
                    wsdPaymentRecordsDTO.setRechargeTimeStart(startOfWeek.atStartOfDay().format(formatter));
                    wsdPaymentRecordsDTO.setRechargeTimeEnd(endOfWeek.atTime(23, 59, 59).format(formatter));
                    break;
                case 2: // 本月
                    LocalDate startOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
                    LocalDate endOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
                    wsdPaymentRecordsDTO.setRechargeTimeStart(startOfMonth.atStartOfDay().format(formatter));
                    wsdPaymentRecordsDTO.setRechargeTimeEnd(endOfMonth.atTime(23, 59, 59).format(formatter));
                    break;
                case 3: // 自定义时间, 前端直接传入
                    // 已经由前端设置好，无需处理
                    break;
                default:
                    throw new IllegalArgumentException("无效的日期类型");
            }
        }

        // 调用MyBatis查询
        return wsdRefundTransactionsMapper.listRefund(wsdPaymentRecordsDTO);
    }

    @Override
    public ChartDataVO getTotalFeeByDateRange(String startDate, String endDate,Long schoolId) {
        List<Map<String, Object>> refundData = wsdRefundTransactionsMapper.getTotalFeeByDateRange(startDate,endDate,schoolId);
        return processRefundData(refundData, 2, startDate, endDate);
    }

    @Override
    public ChartDataVO getTotalFeeByYear(Long schoolId) {
        int currentYear = LocalDate.now().getYear();
        List<Map<String, Object>> refundData = wsdRefundTransactionsMapper.getTotalFeeByMonth(currentYear,schoolId);
        return processRefundData(refundData, 1);
    }

    @Override
    public ChartDataVO getTotalFeeByMonth(Long schoolId) {
        int currentYear = LocalDate.now().getYear();
        List<Map<String, Object>> refundData = wsdRefundTransactionsMapper.getTotalFeeByMonth(currentYear,schoolId);
        return processRefundData(refundData, 0);
    }

    private ChartDataVO processRefundData(List<Map<String, Object>> refundData, int queryType) {
        return processRefundData(refundData, queryType, null, null);
    }


    private ChartDataVO processRefundData(List<Map<String, Object>> refundData, int queryType, String startDate, String endDate) {
        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        int totalAmount = 0;

        if (queryType == 0) {
            // 初始化12个月的值
            for (int i = 1; i <= 12; i++) {
                labels.add(i + "月");
                values.add(0);
            }
        } else if (queryType == 1) {
            // 初始化当前年的每月值
            int currentYear = LocalDate.now().getYear();
            for (int i = 1; i <= 12; i++) {
                labels.add(currentYear + "-" + (i < 10 ? "0" + i : i));
                values.add(0);
            }
        } else if (queryType == 2) {
            // 初始化自定义时间区间的每日值
            LocalDate start = LocalDate.parse(startDate);
            LocalDate end = LocalDate.parse(endDate);
            while (!start.isAfter(end)) {
                labels.add(start.toString());
                values.add(0);
                start = start.plusDays(1);
            }
        }
        //TODO 退款流水统计
        for (Map<String, Object> data : refundData) {
            String period = (String) data.get("period");
            int totalRefundAmount = ((Number) data.get("totalRefundAmount")).intValue();

            if (queryType == 0 || queryType == 1) {
                int month = Integer.parseInt(period.split("-")[1]);
                values.set(month - 1, totalRefundAmount);
            } else {
                int index = labels.indexOf(period);
                if (index != -1) {
                    values.set(index, totalRefundAmount);
                }
            }

            totalAmount += totalRefundAmount;
        }

        ChartDataVO refundChartData = new ChartDataVO();
        refundChartData.setLabels(labels);
        refundChartData.setValues(values);
        refundChartData.setTotalAmount(totalAmount);

        return refundChartData;
    }

    @Override
    public List<RefundManagementVO> refundManagementList(WsdRefundManagementDTO wsdRefundManagementDTO) {
        SysUser user = getLoginUser().getUser();
        Long schoolId = user.getSchoolId();
        if (!user.isAdmin()) {
            if (wsdRefundManagementDTO.getSchoolId()==null) {
                wsdRefundManagementDTO.setSchoolId( schoolId );
            }
        }
        if (wsdRefundManagementDTO.getStartDate()!=null&&wsdRefundManagementDTO.getEndDate()!=null){
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            // 解析日期部分
            LocalDate startLocalDate = LocalDate.parse(wsdRefundManagementDTO.getStartDate(), formatter);
            LocalDate endLocalDate = LocalDate.parse(wsdRefundManagementDTO.getEndDate(), formatter);

            // 设置开始时间为当天的00:00:00
            LocalDateTime startDate = startLocalDate.atStartOfDay();

            // 设置结束时间为当天的23:59:59
            LocalDateTime endDate = endLocalDate.atTime( LocalTime.MAX);
            wsdRefundManagementDTO.setStartTime( startDate );
            wsdRefundManagementDTO.setEndTime( endDate );
        }
        List<RefundManagementVO> wsdRefundTransactionsVOList = wsdRefundTransactionsMapper.refundManagementList(wsdRefundManagementDTO);
        for (RefundManagementVO wsdRefundTransactionsVO : wsdRefundTransactionsVOList){
            //退餐日期
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String refundDate = formatter.format(wsdRefundTransactionsVO.getStartTime()) + " " + formatter.format(wsdRefundTransactionsVO.getEndTime());
            wsdRefundTransactionsVO.setRefundDate( refundDate );
            //退餐数记录表
            List<WsdMealRefundsDTO> list = wsdMealRefundsService.selectWsdMealRefundsListByIds(wsdRefundTransactionsVO.getId());
            //餐数
            Integer breakfast = 0;
            Integer lunch = 0;
            Integer dinner = 0;
            String refundReason = "";
            for (WsdMealRefundsDTO wsdMealRefundsDTO : list){
                if (wsdMealRefundsDTO.getBreakfast()==1){
                    breakfast = breakfast + 1;
                }
                if (wsdMealRefundsDTO.getLunch()==1){
                    lunch = lunch + 1;
                }
                if (wsdMealRefundsDTO.getDinner()==1){
                    dinner = dinner + 1;
                }
            }
            if (breakfast!=0){
                refundReason = refundReason + "早餐："+breakfast + " 餐；";
            }
            if (lunch!=0){
                refundReason = refundReason + "午餐："+lunch + " 餐；";
            }
            if (dinner!=0){
                refundReason = refundReason + "晚餐："+dinner + " 餐；";
            }
            wsdRefundTransactionsVO.setRefundReason( refundReason );
            //退款金额
            if (wsdRefundTransactionsVO.getPayoutStatus()==1){
                BigDecimal refundAmount = BigDecimal.ZERO;
                List<WsdRefundTransactions> wsdRefundTransactions = wsdRefundTransactionsMapper.selectWsdRefundByLeavesIds(wsdRefundTransactionsVO.getId());
                if (!wsdRefundTransactions.isEmpty()) {
                    for (WsdRefundTransactions wsdRefundTransactions1 : wsdRefundTransactions) {
                        refundAmount =  refundAmount.add( wsdRefundTransactions1.getRefundAmount() ) ;
                        if (wsdRefundTransactions1.getRefundAccount() != null&&wsdRefundTransactionsVO.getRefundAccount()!=null) {
                            wsdRefundTransactionsVO.setRefundAccount( wsdRefundTransactions1.getRefundAccount() );
                        }else {
                            wsdRefundTransactionsVO.setRefundAccount( "微信" );
                        }
                    }
                    wsdRefundTransactionsVO.setRefundAmount( refundAmount );
                }else {
                    wsdRefundTransactionsVO.setRefundAccount( "微信" );
                }
            }
        }

        // 调用MyBatis查询
        return wsdRefundTransactionsVOList;
    }

    @Override
    public List<OrderFoodVOTable> refundFood(Long id){
        //查出数据
        RefundManagementVO wsdRefundTransactionsVOList = wsdRefundTransactionsMapper.refundFoodById(id);
        //退餐数记录表
        List<WsdMealRefundsDTO> wsdMealRefundsDTOList = wsdMealRefundsService.selectWsdMealRefundsListByIds(id);
        //每餐的单价
        WsdRechargeRefund wsdRechargeRefund = wsdRechargeRefundService.selectWsdRechargeRefundByConfigId(wsdRefundTransactionsVOList.getConfigId());
        //申请人
        SysUser appl = userService.selectUserById(wsdRefundTransactionsVOList.getParentId());
        //餐数
        Integer breakfast = 0;
        Integer lunch = 0;
        Integer dinner = 0;
        BigDecimal breakfastAmount = new BigDecimal(0);
        BigDecimal lunchAmount = new BigDecimal(0);
        BigDecimal dinnerAmount = new BigDecimal(0);
        String refundReason = "";
        for (WsdMealRefundsDTO wsdMealRefundsDTO : wsdMealRefundsDTOList){
            if (wsdMealRefundsDTO.getBreakfast()==1){
                breakfast = breakfast + 1;
            }
            if (wsdMealRefundsDTO.getLunch()==1){
                lunch = lunch + 1;
            }
            if (wsdMealRefundsDTO.getDinner()==1){
                dinner = dinner + 1;
            }
        }
        //退餐日期
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String refundDate = formatter.format(wsdRefundTransactionsVOList.getStartTime()) + " ~ " + formatter.format(wsdRefundTransactionsVOList.getEndTime());
        List<OrderFoodVOTable> orderFoodVOTableList = new ArrayList<>();
        //学生信息
        OrderFoodVOTable orderFoodVOTable = new OrderFoodVOTable();
        orderFoodVOTable.setTitle( "学生信息" );
        List<OrderFoodTable> orderFoodTableList = new ArrayList<>();
        orderFoodTableList.add(new OrderFoodTable("学生姓名", wsdRefundTransactionsVOList.getStudentName()));
        orderFoodTableList.add(new OrderFoodTable("学校名称", wsdRefundTransactionsVOList.getSchoolName()));
        orderFoodTableList.add(new OrderFoodTable("年级", wsdRefundTransactionsVOList.getGradeName()));
        orderFoodTableList.add(new OrderFoodTable("班级", wsdRefundTransactionsVOList.getClassName()));
        orderFoodTableList.add(new OrderFoodTable("家长手机号", wsdRefundTransactionsVOList.getParentMobile()));
        orderFoodVOTable.setList(orderFoodTableList);
        orderFoodVOTableList.add(orderFoodVOTable);

        if (breakfast>0){
            breakfastAmount = wsdRechargeRefund.getBreakfastFee().multiply( new BigDecimal( breakfast ) );
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "早餐退餐详情" );
            orderFoodTableList = new ArrayList<>();
            orderFoodTableList.add( new OrderFoodTable( "退餐日期", refundDate ) );
            orderFoodTableList.add( new OrderFoodTable( "退餐数", breakfast.toString()  + " 餐") );
            orderFoodTableList.add( new OrderFoodTable( "合计金额", breakfastAmount.toString()  + " 元") );
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }
        if (lunch>0){
            lunchAmount = wsdRechargeRefund.getLunchFee().multiply( new BigDecimal( lunch ) );
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "午餐退餐详情" );
            orderFoodTableList = new ArrayList<>();
            orderFoodTableList.add( new OrderFoodTable( "退餐日期", refundDate ) );
            orderFoodTableList.add( new OrderFoodTable( "退餐数", lunch.toString()  + " 餐") );
            orderFoodTableList.add( new OrderFoodTable( "合计金额", lunchAmount.toString()  + " 元") );
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }
        if (dinner>0){
            dinnerAmount = wsdRechargeRefund.getDinnerFee().multiply( new BigDecimal( dinner ) );
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "晚餐退餐详情" );
            orderFoodTableList = new ArrayList<>();
            orderFoodTableList.add( new OrderFoodTable( "退餐日期", refundDate ) );
            orderFoodTableList.add( new OrderFoodTable( "退餐数", dinner.toString() + " 餐" ) );
            orderFoodTableList.add( new OrderFoodTable( "合计金额", dinnerAmount.toString()  + " 元") );
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }

        if (wsdRefundTransactionsVOList.getPayoutStatus()==1) {
            //退款记录
            List<WsdRefundTransactions> wsdRefundTransactionsList = wsdRefundTransactionsMapper.selectWsdRefundByLeavesIds( id );
            //退费详情
            orderFoodVOTable = new OrderFoodVOTable();
            String title = "退费详情";
            orderFoodVOTable.setTitle( title );
            orderFoodTableList = new ArrayList<>();
            Integer adds = breakfast + lunch + dinner;
            orderFoodTableList.add( new OrderFoodTable( "退餐总数", adds.toString() + " 餐" ) );
            BigDecimal refundAmount = BigDecimal.ZERO;
            int i= 1;
            for (WsdRefundTransactions wsdRefundTransactions : wsdRefundTransactionsList){
                refundAmount = refundAmount.add( wsdRefundTransactions.getRefundAmount() );
                String mealType = "";
                if (wsdRefundTransactions.getMealType()!=null) {
                    switch (wsdRefundTransactions.getMealType()) {
                        case 0:
                            mealType = "(早餐)";
                            break;
                        case 1:
                            mealType = "(午餐)";
                            break;
                        case 2:
                            mealType = "(晚餐)";
                            break;
                        default:
                            mealType = "(早餐+午餐)";
                    }
                }
                orderFoodTableList.add( new OrderFoodTable( "退费金额"+i, wsdRefundTransactions.getRefundAmount().toString() + " 元"+mealType ) );
                if (wsdRefundTransactions.getRefundAccount()==null) {
                    orderFoodTableList.add( new OrderFoodTable( "退费方式" + i, "微信" ) );
                }else {
                    orderFoodTableList.add( new OrderFoodTable( "退费方式" + i, wsdRefundTransactions.getRefundAccount() ) );
                }
                DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                orderFoodTableList.add( new OrderFoodTable( "退费时间"+i, wsdRefundTransactions.getRefundDate().format( formatter1 ) ) );
                i++;
            }
            orderFoodTableList.add( new OrderFoodTable( "合计退费金额", refundAmount.toString() + " 元" ) );
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }
        if (wsdRefundTransactionsVOList.getPayoutStatus()!=2){

        }

        RefundApproval refundApproval = new RefundApproval();
        refundApproval.setLeaveId(wsdRefundTransactionsVOList.getId());
        List<RefundApproval> list = refundApprovalService.selectRefundApprovalList(refundApproval);
        if (list.size()>0){
            //审核详情
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "审核详情" );
            for (int i = 0; i < list.size(); i++){
                //审批状态
                String approvalStatus = "";
                if (list.get( i ).getRefundApprovalStatus() == 0) {
                    approvalStatus = "不同意";
                } else if (list.get( i ).getRefundApprovalStatus() == 1) {
                    approvalStatus = "同意";
                } else if (list.get( i ).getRefundApprovalStatus() == 2) {
                    approvalStatus = "待审批";
                }
                //审批人
                SysUser sysUser = userService.selectUserById(list.get(i).getApproverUserId());
                if (list.size()==1) {
                    orderFoodTableList = new ArrayList<>();
                    orderFoodTableList.add( new OrderFoodTable( "类型", "家长代收款" ) );
                    orderFoodTableList.add( new OrderFoodTable( "申请账号", appl.getUserName() ) );
                    orderFoodTableList.add( new OrderFoodTable( "审批账号", sysUser.getUserName() ) );
                    orderFoodTableList.add( new OrderFoodTable( "审批人", sysUser.getNickName() ) );
                    orderFoodTableList.add( new OrderFoodTable( "审批状态", approvalStatus ) );
                    if (list.get( i ).getRefundApprovalStatus() == 0) {
                        orderFoodTableList.add( new OrderFoodTable( "不通过原因", list.get( i ).getRefundComment() ) );
                    }
                    orderFoodVOTable.setList( orderFoodTableList );
                }
                else {
                    orderFoodTableList = new ArrayList<>();
                    String title = "审核记录"+i;
                    orderFoodTableList.add( new OrderFoodTable( title, "  " ) );
                    orderFoodTableList.add( new OrderFoodTable( "类型", "家长代收款" ) );
                    orderFoodTableList.add( new OrderFoodTable( "申请账号", appl.getUserName() ) );
                    orderFoodTableList.add( new OrderFoodTable( "审批账号", sysUser.getUserName() ) );
                    orderFoodTableList.add( new OrderFoodTable( "审批人", sysUser.getNickName() ) );
                    orderFoodTableList.add( new OrderFoodTable( "审批状态", approvalStatus ) );
                    if (list.get( i ).getRefundApprovalStatus() == 0) {
                        orderFoodTableList.add( new OrderFoodTable( "不通过原因", list.get( i ).getRefundComment() ) );
                    }
                    orderFoodVOTable.setList( orderFoodTableList );
                }
            }
            orderFoodVOTableList.add(orderFoodVOTable);
        }

        return orderFoodVOTableList;
    }

    @Override
    public WsdRefundTransactions selectWsdRefundByLeavesId(Long leavesId){
        return wsdRefundTransactionsMapper.selectWsdRefundByLeavesId(leavesId);
    }
    @Override
    public OrderPeopleNumVO orderPeopleNum(WsdRefundManagementDTO wsdRefundManagementDTO){
        SysUser user = getLoginUser().getUser();
        Long schoolId = user.getSchoolId();
        if (!user.isAdmin()) {
            if (wsdRefundManagementDTO.getSchoolId()==null) {
                wsdRefundManagementDTO.setSchoolId( schoolId );
            }
        }
        if (wsdRefundManagementDTO.getStartDate()!=null&&wsdRefundManagementDTO.getEndDate()!=null){
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            // 解析日期部分
            LocalDate startLocalDate = LocalDate.parse(wsdRefundManagementDTO.getStartDate(), formatter);
            LocalDate endLocalDate = LocalDate.parse(wsdRefundManagementDTO.getEndDate(), formatter);

            // 设置开始时间为当天的00:00:00
            LocalDateTime startDate = startLocalDate.atStartOfDay();

            // 设置结束时间为当天的23:59:59
            LocalDateTime endDate = endLocalDate.atTime( LocalTime.MAX);
            wsdRefundManagementDTO.setStartTime( startDate );
            wsdRefundManagementDTO.setEndTime( endDate );
        }
//        wsdRefundManagementDTO.setPayoutStatus( 1L );
        OrderPeopleNumVO orderPeopleNum = wsdRefundTransactionsMapper.orderPeopleNum(wsdRefundManagementDTO);
        return orderPeopleNum;
    }
}
